package com.itfreer.ui.photoview;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.itfreer.core.config.ConfigManager;
import com.itfreer.core.file.FileMeta;
import com.itfreer.core.file.path.FileService;
import com.itfreer.core.file.path.FileUpload;
import com.itfreer.ui.R;
import com.itfreer.ui.base.GridView;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.FileProvider;

public class PhotoViewPager extends GridView {

    private Activity pActivity;

    private PhotoListAdapter adapter;
    // 拍照后原图回存入此路径下
    private File imageFile;
    // 拍视频的地址
    private File videoFile;
    // 当前文件
    private List<String> files = new ArrayList<>();
    // 当前文件
    private List<FileMeta> fileMetas = new ArrayList<>();

    public void setActivity(Activity pActivity) {
        this.pActivity = pActivity;
    }

    public List<FileMeta> getFileMetas() {
        return fileMetas;
    }

    public PhotoViewPager(@NonNull Context context) {
        super(context);
    }

    public PhotoViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PhotoViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void bindData(FileMeta[] fileMetas, Boolean readonly) {
        if(fileMetas==null) {
            fileMetas = new FileMeta[0];
        }
        for(FileMeta fileMeta: fileMetas){
            this.fileMetas.add(fileMeta);
            String file = FileService.instance.getFile("plupload", fileMeta.getKey());
            File curFile = new File(file);
            // 如果本地资源存在就使用本地资源，不存在就使用在线资源
            if(curFile.exists()) {
                this.files.add(file);
            } else {
                if (fileMeta.getUrl() != null && !"".equals(fileMeta.getUrl())) {
                    this.files.add(fileMeta.getUrl());
                } else {
                    if (ConfigManager.getFilePath() != null) {
                        String fileUrl = ConfigManager.getFilePath() + "file/" + fileMeta.getBucketName() + "/" + fileMeta.getKey();
                        this.files.add(fileUrl);
                    } else {
                        this.files.add(file);
                    }
                }
            }
        }
        this.files.add(null);
        adapter = new PhotoListAdapter(pActivity, this, files, readonly);
        this.setAdapter(adapter);
    }

    /**
     * 添加
     */
    public void add() {
        AlertDialog.Builder builder = new AlertDialog.Builder(pActivity);
        LayoutInflater inflater = pActivity.getLayoutInflater();
        // 获取自定义布局
        View layout = inflater.inflate(R.layout.dialog_select_photo, null);
        builder.setView(layout);
        final AlertDialog dlg = builder.create();
        Window window = dlg.getWindow();
        window.setGravity(Gravity.BOTTOM);
        // 设置点击外围消散
        dlg.setCanceledOnTouchOutside(true);
        dlg.show();

        WindowManager m = pActivity.getWindowManager();
        // 为获取屏幕宽、高
        Display d = m.getDefaultDisplay();
        // 获取对话框当前的参数值
        WindowManager.LayoutParams p = dlg.getWindow().getAttributes();
        // 宽度设置为屏幕
        p.width = d.getWidth();
        window.setBackgroundDrawable(new ColorDrawable(0));

        TextView photograph = layout.findViewById(R.id.photograph);
        TextView videograph = layout.findViewById(R.id.videograph);

        TextView photo = layout.findViewById(R.id.photo);
        TextView video = layout.findViewById(R.id.video);

        TextView cancel = layout.findViewById(R.id.cancel);

        // 拍照
        photograph.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                takePhoto();
                dlg.dismiss();
            }
        });

        // 拍视频
        videograph.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                takeVideo();
                dlg.dismiss();
            }
        });

        // 从相册中选照片
        photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                choosePhoto();
                dlg.dismiss();
            }
        });

        // 从相册中选视频
        video.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                chooseVideo();
                dlg.dismiss();
            }
        });

        // 取消
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                dlg.dismiss();
            }
        });
    }

    private void takePhoto() {
        Intent intent = new Intent();
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        // 获取文件
        imageFile = createImageFile();
        Uri imageUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            /*7.0以上要通过FileProvider将File转化为Uri*/
            imageUri = FileProvider.getUriForFile(pActivity, pActivity.getApplication().getPackageName() + ".provider", imageFile);
        } else {
            /*7.0以下则直接使用Uri的fromFile方法将File转化为Uri*/
            imageUri = Uri.fromFile(imageFile);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        pActivity.startActivityForResult(intent, 1);
    }

    private void takeVideo() {
        // 获取文件
        videoFile = createVideoFile();
        Uri imageUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            /*7.0以上要通过FileProvider将File转化为Uri*/
            imageUri = FileProvider.getUriForFile(pActivity, pActivity.getApplication().getPackageName() + ".provider", videoFile);
        } else {
            /*7.0以下则直接使用Uri的fromFile方法将File转化为Uri*/
            imageUri = Uri.fromFile(videoFile);
        }

        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        // 设置视频录制的最长时间
        intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 120);
        // 设置视频录制的画质
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        // 将文件另存为
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        pActivity.startActivityForResult(intent, 2);
    }

    /**
     * 创建用来存储图片的文件，以时间来命名就不会产生命名冲突
     */
    private static File createImageFile() {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File imageFile = null;
        try {
            imageFile = File.createTempFile(imageFileName, ".jpg", storageDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageFile;
    }

    /**
     * 创建用来存储视频的文件，以时间来命名就不会产生命名冲突
     */
    private static File createVideoFile() {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "VIDEO_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File imageFile = null;
        try {
            imageFile = File.createTempFile(imageFileName, ".mp4", storageDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageFile;
    }

    /**
     * 选择照片
     */
    private void choosePhoto() {
        //这是打开系统默认的相册(就是你系统怎么分类,就怎么显示,首先展示分类列表)
        Intent picture = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        pActivity.startActivityForResult(picture, 3);
    }

    /**
     * 选择视频
     */
    private void chooseVideo() {
        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
        pActivity.startActivityForResult(i, 4);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 拍照
        if (requestCode == 1 && resultCode != Activity.RESULT_CANCELED) {
            String state = Environment.getExternalStorageState();
            if (!state.equals(Environment.MEDIA_MOUNTED)) return;
            String path = imageFile.getPath();
            saveFile(path);
        } else if (requestCode == 2 && resultCode != Activity.RESULT_CANCELED) {
            // 拍视频
            String state = Environment.getExternalStorageState();
            if (!state.equals(Environment.MEDIA_MOUNTED)) return;
            String path = videoFile.getPath();
            saveFile(path);
        } else if (requestCode == 3 && resultCode == Activity.RESULT_OK && null != data) {
            // 选照片
            Uri selectedImage = data.getData();
            String path = getRealPathFromUri(selectedImage);// 需要转换路径格式
            saveFile(path);
        } else if (requestCode == 4 && resultCode == Activity.RESULT_OK && null != data) {
            // 选视频
            Uri selectedImage = data.getData();
            String path = getRealPathFromUri(selectedImage);// 需要转换路径格式
            saveFile(path);
        }
    }

    public String getRealPathFromUri(Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = pActivity.getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    private void saveFile(String path) {
        if(path.startsWith("/raw/")){
            path = path.substring(5);
        }
        byte[] content = getImageStream(path);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String ymd = sdf.format(new Date());
        String[] files = path.split("\\.");
        String objectKey = ymd + "/" + UUID.randomUUID().toString().replace("-", "") + "." + files[files.length-1];
        FileUpload.instance.putObject("plupload", objectKey, content);

        String file = FileService.instance.getFile("plupload", objectKey);
        if(this.files.size()>0){
            this.files.remove(this.files.size()-1);
        }
//        this.files.add(file);
        this.files.add(path);// 修改为本地资源
        this.files.add(null);
        FileMeta fileMeta = new FileMeta();
        fileMeta.setBucketName("plupload");
        fileMeta.setKey(objectKey);
        this.fileMetas.add(fileMeta);

        this.adapter.notifyDataSetChanged();
    }

    private static byte[] getImageStream(String path) {
        byte[] buffer = null;
//        File file = new File(path);
        // 压缩图片
        File file = compressImage2FileBySize(path);
        FileInputStream fis;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
        int size = buffer.length / 1024;
        System.out.println(size);
        return buffer;
    }

    /**
     * 删除
     * @param position
     */
    public void del(int position) {
        files.remove(position);
        if(fileMetas.size()>=position+1) {
            fileMetas.remove(position);
        }
        this.adapter.notifyDataSetChanged();
    }

    /*
     * 图片的质量压缩 降低图片质量
     * 原理 ：通过算法扣掉（同化）了 图片中的一些某个点附近相近的像素，达到降低质量 减少 文件大小的目的
     * 注意 ： 他其实只能 实现对 file 的影响，对加载这个图片出来的bitmap 内存是无法节省的 ，还是那么大
     *  因为 bitmap 在内存中的大小是按照 像素 计算的 ，也就是width * height ，对于质量压缩，并不会改变图片的真实的像素（像素大小不会变）。
     *  使用场景 ：
     *      将图片保存到本地 ，或者将图片上传 到服务器 ，根据实际需求来 。
     * */
    public static File compressImage2File(String path) {
        File imageFile = new File(path); //图片的路径
        String[] paths = path.split("\\.");
        if (paths.length !=2) {
            System.out.println("图片路径有误！" + path);
            return new File(path);
        }
        File file = new File(paths[0] + "_bmp." + paths[1]);
        if (!file.exists()) {
            try {
                file.createNewFile();
            }catch (Exception e){
                System.out.println("创建新文件出错");
            }
        }
        BitmapFactory.Options opts = new BitmapFactory.Options();
        Bitmap bmp = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), opts);// 文件路径

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG,50,bos);
        try {
            FileOutputStream fos = new FileOutputStream(file) ;
            fos.write(bos.toByteArray());
            System.out.println("质量压缩成功");
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 2.尺寸压缩
     * 原理 ： 通过减少单位尺寸的像素值，真正意义上的降低像素值。
     * 使用场景 ： 缓存缩略图 (头像的处理)
     */
    public static File compressImage2FileBySize(String path) {
        File imageFile = new File(path); //图片的路径
        int imgSize = (int) (imageFile.length()/1024);
        System.out.println("当前图片大小(Kb)：" + imgSize);
        if (imgSize < 1024) { // 小于1M的图片不做处理
            return imageFile;
        }
        String[] paths = path.split("\\.");
        if (paths.length !=2) {
            System.out.println("图片路径有误！" + path);
            return new File(path);
        }
        File file = new File(paths[0] + "_bmp." + paths[1]);
        if (!file.exists()) {
            try {
                file.createNewFile();
            }catch (Exception e){
                System.out.println("创建新文件出错");
            }
        }
        BitmapFactory.Options opts = new BitmapFactory.Options();
        Bitmap bmp = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), opts);// 文件路径

        //压缩尺寸倍数 值越大 ，图片的尺寸就越小
        int ratio = 4;
        Bitmap result = Bitmap.createBitmap(bmp.getWidth() /ratio , bmp.getHeight() / ratio ,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result) ;
        Rect rect = new Rect(0,0,bmp.getWidth() / ratio ,bmp.getHeight() / ratio );
        canvas.drawBitmap(bmp,null,rect,null);

        ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
        result.compress(Bitmap.CompressFormat.JPEG,100,bos);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bos.toByteArray());
            System.out.println("尺寸压缩成功");
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

}
